package com.justdoit.facedemo.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.arcsoft.face.FaceEngine;
import com.arcsoft.face.FaceFeature;
import com.arcsoft.face.FaceInfo;
import com.arcsoft.face.FaceSimilar;
import com.arcsoft.face.enums.CompareModel;
import com.arcsoft.face.toolkit.ImageInfoEx;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.justdoit.facedemo.base.Result;
import com.justdoit.facedemo.base.Results;
import com.justdoit.facedemo.domain.User;
import com.justdoit.facedemo.mapper.UserMapper;
import com.justdoit.facedemo.utils.ArcFaceUtils;
import com.justdoit.facedemo.utils.ArcFaceWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**  测试类
 * @author: He Wentao
 * @date: 2022/6/19 21:02
 * <p>
 * 模拟测试类
 */
@RestController
@RequestMapping("/test")
public class ControllerTest {

    // redis
    private final StringRedisTemplate redisTemplate;

    // MP
    private final UserMapper userMapper;

    // 人脸识别
    private final ArcFaceWorker faceWorker;

    public ControllerTest(StringRedisTemplate redisTemplate, UserMapper userMapper, ArcFaceWorker faceWorker) {
        this.redisTemplate = redisTemplate;
        this.userMapper = userMapper;
        this.faceWorker = faceWorker;
    }

    // 模拟添加缓存数据
    @GetMapping("/add")
    public void redisTest() {
        System.out.println("---------------");
        redisTemplate.opsForHash().put("Fae", "人脸id", new String(new byte[1024], StandardCharsets.UTF_8));
    }

    // 模拟读取缓存数据
    @GetMapping("/select")
    public Result<Map<String, String>> redis() {
        final List<Object> fae = redisTemplate.opsForHash().values("Fae");
        // 转换为二进制
        // byte[] blob = new String(String.valueOf(fae.get(0))).getBytes(StandardCharsets.UTF_8);

        final HashMap<String, String> map = new HashMap<>();
        map.put("Fae", String.valueOf(fae.get(0)));
        return Results.newSuccess(map);
    }

    // 从MySQL读取数据，放入缓存，只读取用户id，和人脸信息，避免用户修改用户信息，频繁更新缓存
    @GetMapping("/getSql")
    public Object getSql() {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.select("*");
        final List<User> users = userMapper.selectList(userQueryWrapper);
        System.out.println(users);
        // redisTemplate.opsForList().leftPush("Face",users.toString());
        return users;
    }


    /**
     * 添加用户人脸
     * @param file  编码图片
     * @param userID    用户唯一id
     * @return  添加状态
     */
    @PostMapping("/addRace")
    public Result<Object> filesUpload(@RequestParam("file") String file,@RequestParam("id")String userID) {
        // 去除开头的 data:image/jpg;base64, 字符，不然无法解析
        file = file.substring(22);

        // 将 64 编码图片，转换为 二进制
        BASE64Decoder decoder = new BASE64Decoder();
        byte[]decoderBytes=null;
        try {decoderBytes=decoder.decodeBuffer(file);}
        catch(IOException e){e.printStackTrace();}

        // 使用图片处理类，进行处理图片，可以获得两个包装类：原始图片信息、二次包装图片信息
        ArcFaceUtils.ImageInfoMeta imageInfoMeta = ArcFaceUtils.packImageInfoMeta(decoderBytes);

        // 调用人脸检测方法，传入二次包装类，返回人脸信息集合
        List<FaceInfo> faceInfos = faceWorker.detectFace(imageInfoMeta.getImageInfoEx());

        // 人脸特征提取，成功后获得人脸特征信息，失败为 null
        FaceFeature faceFeature = faceWorker.extractFaceFeature(faceInfos, imageInfoMeta.getImageInfoEx());

        // 如果不为null，则将特征信息，放到缓存中
        if (faceFeature != null) {

            // 测试和本地图片对比
           /* final File file1 = new File("D:\\迅雷云盘\\FacePartSystem\\FacePartSystemJava\\src\\main\\resources\\static\\拍照图片.png");
            final ArcFaceUtils.ImageInfoMeta imageInfoMeta1 = ArcFaceUtils.packImageInfoEx(file1);
            final List<FaceInfo> faceInfos1 = faceWorker.detectFace(imageInfoMeta1.getImageInfoEx());
            final FaceFeature faceFeature1 = faceWorker.extractFaceFeature(faceInfos1, imageInfoMeta1.getImageInfoEx());

            if (faceFeature1!=null){
                final FaceSimilar faceSimilar1 = faceWorker.compareFaceFeature(faceFeature1, faceFeature, CompareModel.LIFE_PHOTO);
                System.out.println("相似度为"+faceSimilar1.getScore());
            }*/


            // 修改数据库 blob 类型二进制数据
            User user = new User();
            user.setUserId(Integer.parseInt(userID));
            user.setUserFaceFeature(decoderBytes);
            userMapper.updateFace(user);

            System.out.println(userID);

            //redisTemplate.opsForHash().put("Fae", "人脸id", new String(faceFeature.getFeatureData(), StandardCharsets.UTF_8));
            return Results.newError("获取成功");
        } else {
            return Results.newError("获取失败");
        }

    }

    @GetMapping("/res")
    public void ResTest(HttpServletResponse response){
        try {
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().println(JSON.toJSONString(Results.newError("非法请求！！！")));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

